參考資料:
Alex老師教學
pjchender筆記
JS30-Day16-Mouse Move Shadow
鐵人賽30天結束後偷懶了幾天才繼續來練習。
隨滑鼠移動的陰影。
抓取節點並做出監聽
const hero = document.querySelector('.hero');
hero.addEventListener('mousemove', shadow);
開始製作內容
let shadow = e => {
console.log(e);
};
用滑鼠滑一下可以看到:(框內是要使用的屬性)
要使用e.offsetX和e.offsetY,有以下幾種作法
let shadow = e => {
// console.log(e);
// 傳統作法
let x = e.offsetX;
let y = e.offsetY;
// 比較新的作法 - 把offsetX, offsetY拆出來
let { offsetX, offsetY } = e;
// 更加新的作法- 把offsetX, offsetY拆出來後命名成x,y
let { offsetX: x, offsetY: y } = e;
};
看左上角接近(0,0)和右下角接近(1,1)的數值
console.log(
offsetX / this.offsetWidth,
offsetY / this.offsetHeight
);
但這時會發現只要滑到文字上,數值就會不正確,因為是另一個座標,必須手動把距離加回去
// 觸發的座標不是hero而是內層,就補回距離
if (e.target !== this) {
offsetX += e.target.offsetLeft;
offsetY += e.target.offsetTop;
}
開始製作陰影
const text = document.querySelector('h1'); //要做出陰影的節點
let moveLength = 100; //陰影移動距離
移動座標
let moveX = Math.floor((offsetX / this.offsetWidth) * moveLength);
let moveY = Math.floor((offsetY / this.offsetHeight) * moveLength);
// 整數化,無條件捨去
紅色陰影*1
text.style.textShadow=`
${moveX}px ${moveY}px 3px rgba(255,0,0,0.8)
`
綠色陰影,出現位置在滑鼠反方向
text.style.textShadow = `
${moveX*-1}px ${moveY*-1}px 3px rgba(0,255,0,0.8)
`;
修改陰影數據,使滑鼠滑到反方向也可以呈現
let moveX = Math.floor((offsetX / this.offsetWidth) * moveLength) * 2 - moveLength;
let moveY = Math.floor((offsetY / this.offsetHeight) * moveLength) * 2 - moveLength;
// 整數化,無條件捨去
陰影效果
text.style.textShadow = `
${moveX}px ${moveY}px 1px rgba(255,0,0,0.8),
${moveX * -1}px ${moveY * -1}px 2px rgba(0,255,0,0.8),
${moveX}px ${moveY * -1}px 3px rgba(0,0,255,0.8),
${moveX * -1}px ${moveY}px 4px rgba(200,255,255,0.8)
`;
視差效果
text.style.textShadow = `
${moveX*-0.3}px ${moveY*-0.3}px 1px rgba(255,0,0,0.8),
${moveX * -1}px ${moveY * -1}px 2px rgba(0,255,0,0.8),
${moveX*-0.6}px ${moveY * -0.6}px 3px rgba(0,0,255,0.8)
`;
改成箭頭函式
(function () {
const hero = document.querySelector('.hero'); //陰影移動的範圍
const text = document.querySelector('h1'); //要做出陰影的節點
let moveLength = 100; //陰影移動距離
let shadow = e => {
// function shadow(e) {
// 拆出滑鼠移動的座標
// 傳統作法
// let x = e.offsetX;
// let y = e.offsetY;
// 比較新的作法 - 把offsetX, offsetY拆出來
// let { offsetX, offsetY } = e;
let { offsetX, offsetY, target, currentTarget } = e;
// 更加新的作法 - 把offsetX, offsetY拆出來後命名成x,y
// let { offsetX: x, offsetY: y } = e;
// console.log(e.target.offsetLeft);
// console.log(e.target.offsetTop);
// 觸發的座標不是hero而是內層,就補回距離
// if (e.target !== this) {
// 如果用箭頭函式,此處this可以換成e.currentTarget
if (target !== currentTarget) {
offsetX += target.offsetLeft;
offsetY += target.offsetTop;
}
// let moveX = Math.floor((offsetX / this.offsetWidth) * moveLength) * 2 - moveLength;
// let moveY = Math.floor((offsetY / this.offsetHeight) * moveLength) * 2 - moveLength;
let moveX = Math.floor((offsetX / currentTarget.offsetWidth) * moveLength) * 2 - moveLength;
let moveY = Math.floor((offsetY / currentTarget.offsetHeight) * moveLength) * 2 - moveLength;
// 整數化,無條件捨去
// text.style.textShadow = `
// ${moveX}px ${moveY}px 1px rgba(255,0,0,0.8),
// ${moveX * -0.5}px ${moveY * -2}px 2px rgba(0,255,0,0.8),
// ${moveX*-0.3}px ${moveY * -0.6}px 3px rgba(0,0,255,0.8),
// ${moveX * -1.5}px ${moveY*-0.3}px 4px rgba(200,255,255,0.8)
// `;
text.style.textShadow = `
${moveX * -0.3}px ${moveY * -0.3}px 1px rgba(255,0,0,0.8),
${moveX * -1}px ${moveY * -1}px 2px rgba(0,255,0,0.8),
${moveX * -0.6}px ${moveY * -0.6}px 3px rgba(0,0,255,0.8)
`;
};
hero.addEventListener('mousemove', shadow);
})();